import { sm3, sm4 } from 'sm-crypto'

// SM4加密配置 - 与后端保持一致
// sm-crypto库要求SM4密钥和初始向量必须是32字符的十六进制字符串
export const sm4Config = {
  // 后端DEFAULT_KEY: "0123456789abcdef0123456789abcdef"
  key: '0123456789abcdef0123456789abcdef', // 32字符十六进制字符串
  // 后端DEFAULT_IV: "0123456789abcdef"
  iv: '0123456789abcdef0123456789abcdef' // 32字符十六进制字符串
}

/**
 * 将十六进制字符串转换为字节数组
 * @param {string} hex - 十六进制字符串
 * @returns {Uint8Array} 字节数组
 */
function hexToBytes(hex) {
  const bytes = new Uint8Array(hex.length / 2);
  for (let i = 0; i < hex.length; i += 2) {
    bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
  }
  return bytes;
}

/**
 * 获取URL中的回调地址
 * @returns {string} 回调地址，如果不存在则返回空字符串
 */
export const getRedirectUrl = () => {
  const query = new URLSearchParams(window.location.search)
  return query.get('redirectUrl') || ''
}

/**
 * 使用SM3加密密码
 * @param {string} password - 需要加密的密码
 * @returns {string} SM3加密后的密码（十六进制字符串）
 */
export const encryptPasswordWithSM3 = (password) => {
  return sm3(password)
}

/**
 * 使用SM4加密数据 - 与后端保持一致的CBC模式
 * @param {string} data - 需要加密的数据
 * @returns {string} SM4加密后的密码（十六进制格式）
 * @throws {Error} 加密失败时抛出错误
 */
export const encryptWithSM4 = (data) => {
  try {
    // 确保数据格式正确
    if (typeof data !== 'string') {
      data = String(data)
    }
    
    // 后端使用CBC模式，前端也需要使用相同模式
    // sm-crypto库的encrypt方法参数格式：encrypt(text, key, options)
    const encryptData = sm4.encrypt(data, sm4Config.key, {
      mode: 'cbc',  // 与后端CBCBlockCipher保持一致
      iv: sm4Config.iv,  // 与后端ParametersWithIV保持一致
      padding: 'pkcs#7'  // 与后端PaddedBufferedBlockCipher保持一致
    })
    
    // 返回十六进制格式的密文
    return encryptData
  } catch (error) {
    console.error('SM4加密失败:', error)
    throw new Error('SM4加密失败')
  }
}

/**
 * 根据后端逻辑修改：仅使用SM4加密SM3哈希结果
 * @param {string} password - 原始密码
 * @returns {string} 加密后的密码
 * @throws {Error} 加密失败时抛出错误
 */
export const encryptPassword = (password) => {
  try {
    // 第一步：使用SM3加密原始密码，得到十六进制字符串
    const sm3Result = encryptPasswordWithSM3(password)
    
    // 第二步：仅使用SM4-CBC模式加密SM3的结果
    // 根据后端逻辑，只需要进行SM4加密
    const encryptedPassword = encryptWithSM4(sm3Result)
    
    // 返回十六进制格式的密文
    return encryptedPassword
  } catch (error) {
    console.error('密码加密失败:', error)
    throw new Error('密码加密失败')
  }
}

/**
 * 构建SSO登录请求参数 - 确保与后端API参数匹配
 * @param {string} username - 用户名
 * @param {string} password - 明文密码
 * @param {string} redirectUrl - 回调地址
 * @returns {Object} 登录请求参数
 */
export const buildLoginParams = (username, password, redirectUrl) => {
  // 对密码进行SM3+SM4加密
  const encryptedPassword = encryptPassword(password)
  
  // 返回与后端API期望的参数格式
  return {
    username,
    password: encryptedPassword,
    redirectUrl
  }
}

/**
 * 处理SSO登录成功后的跳转逻辑
 * @param {string} redirectUrl - 回调地址
 * @param {string} defaultRoute - 默认跳转地址，当没有回调地址时使用
 */
export const handleLoginRedirect = (redirectUrl, defaultRoute = '/') => {
  if (redirectUrl) {
    window.location.href = redirectUrl
  } else {
    window.location.href = defaultRoute
  }
}

/**
 * 解析URL查询参数
 * @returns {Object} URL查询参数对象
 */
export const parseUrlParams = () => {
  const params = {}
  const query = new URLSearchParams(window.location.search)
  for (const [key, value] of query.entries()) {
    params[key] = value
  }
  return params
}